﻿
using Catel;
using Catel.IoC;
using Catel.Logging;
using Catel.MVVM;
using Catel.MVVM.Services;
using Shell.Library.Models;
using Shell.Library.Modules;
using Shell.Library.Services;
using Microsoft.Practices.Prism.Modularity;
using Shell.Services;
using Shell.ViewModels;
using Shell.Views;
using System;
using System.IO;
using System.Windows;

namespace Shell
{
    /// <summary>
    /// The bootstrapper that will create and run the shell.
    /// </summary>
    public class ShellBootstrapper : BootstrapperBase<MainWindow>
    {
        /// <summary>
        /// The log.
        /// </summary>
        private static readonly ILog Log = LogManager.GetCurrentClassLogger();

        private readonly bool _createAboutRibbon;

        #region Constructors
        /// <summary>
        /// Initializes a new instance of the <see cref="ShellBootstrapper" /> class.
        /// </summary>
        /// <param name="createAboutRibbon">if set to <c>true</c>, a ribbon item for the about box will be created.</param>
        public ShellBootstrapper(bool createAboutRibbon = true)
        {
#if DEBUG
            LogManager.RegisterDebugListener();
#endif
            _createAboutRibbon = createAboutRibbon;

            Log.Debug("Optimizing performance by disable the WarningAndErrorValidator in Catel");

            Catel.Windows.Controls.UserControl.DefaultCreateWarningAndErrorValidatorForViewModelValue = false;
            Catel.Windows.Controls.UserControl.DefaultSkipSearchingForInfoBarMessageControlValue = true;

            Log.Info("Loading application themes");

            // Force loading of type
            var ribbonType = typeof(Fluent.Ribbon);
            Log.Debug("Loaded ribbon type '{0}'", ribbonType.Name);

            var application = Application.Current;
            application.Resources.MergedDictionaries.Add(new ResourceDictionary
            {
                Source = new Uri("pack://application:,,,/Fluent;Component/Themes/Office2010/Silver.xaml", UriKind.RelativeOrAbsolute)
            });
            application.Resources.MergedDictionaries.Add(new ResourceDictionary
            {
                Source = new Uri("/Catel.Extensions.Controls;component/themes/generic.xaml", UriKind.RelativeOrAbsolute)
            });

            string modulesDirectory = ModulesDirectory;
            if (!Directory.Exists(modulesDirectory))
            {
                Log.Warning("Modules path '{0}' is missing, creating it", modulesDirectory);

                Directory.CreateDirectory(modulesDirectory);
            }

            ServiceLocator.Default.RegisterInstance<IConfigurationService>(new ConfigurationService());
        }
        #endregion

        #region Properties

        /// <summary>
        /// The modules directory.
        /// </summary>
        //private string ModulesDirectory { get { return Path.Combine(".", ModuleBase.ModulesDirectory); } }
        private string ModulesDirectory { get { return Directory.GetCurrentDirectory(); } }

        #endregion

        #region Methods
        /// <summary>
        /// Creates the <see cref="T:Microsoft.Practices.Prism.Modularity.IModuleCatalog"/> used by Prism.
        /// </summary>
        protected override IModuleCatalog CreateModuleCatalog()
        {
            var moduleCatalog = new DirectoryModuleCatalog { ModulePath = ModulesDirectory };

            moduleCatalog.Initialize();

            return moduleCatalog;
        }

        /// <summary>
        /// Configures the IoC container.
        /// </summary>
        protected override void ConfigureContainer()
        {
            base.ConfigureContainer();

            Container.RegisterType<IShellService, ShellService>();
            Container.RegisterType<IRibbonService, RibbonService>();      
        }

        /// <summary>
        /// Initializes the modules. May be overwritten in a derived class to use a custom Modules Catalog.
        /// </summary>
        protected override void InitializeModules()
        {
            var configurationService = (IConfigurationService)ServiceLocator.Default.GetService(typeof(IConfigurationService));

            base.InitializeModules();

            if (_createAboutRibbon)
            {
                var ribbonService = Container.ResolveType<IRibbonService>();
                ribbonService.RegisterRibbonItem(new RibbonButton(configurationService.Configuration.HelpTabText, configurationService.Configuration.HelpGroupText, configurationService.Configuration.HelpButtonText, new Command(() =>
                {
                    var uiVisualizerService = Container.ResolveType<IUIVisualizerService>();
                    uiVisualizerService.ShowDialog(new AboutViewModel());
                })));
            }
        }

        #endregion
    }
}